﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="height: 100%;border: none;padding: 0px;margin: 0px;">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
	<meta http-equiv="X-UA-Compatible" content="IE=10; IE=9; IE=8; IE=7;  IE=EDGE"/>
	<meta content="JobComposer" name="keywords" />
	<meta content="JobComposer" name="description" />
	<meta name="generator" content="JobComposer"/>
	<link rel="shortcut icon" href="/static/images/favicon.ico" type="image/x-icon" />
	<title>Demo-Malakas</title>
    
    <script src="go.js"></script>
    <script src="../extensions/DataInspector.js"></script>
    <script src="../extensions/Robot.js"></script>
	
	<link href="../assets/css/goSamples.css" rel="stylesheet" type="text/css" />  <!-- you don't need to use this -->
	<script src="goSamples.js"></script>  <!-- this is only for the GoJS Samples framework -->
	<!-- <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" /> -->
	<style type="text/css">
	</style>
</head>
<body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main" style="padding:5px;">
                <div id="myDiagramDiv" style="border: solid 1px #DAE4E4; width:100%; height:500px;background-color: #DAE4E4;"></div>
                <div>
                    <div id ="diagramEventsMsg"></div>
                  <button onclick="layout()">Re-layout Diagram</button>
                  <button id="SaveButton" onclick="save()">Save</button>
                  <button onclick="load()">Load</button>
                  <button onclick="zoomToFit()">zoomToFit</button>
                  <button onclick="exportToPNG()">exportToPNG</button><br />
                  <textarea id="mySavedModel" style="width:100%;height:300px">

			  
			  
			  
                </textarea>
                <div id="id_image_export"></div>
                </div>
                
                
                
                
            </div>


        </div>
    </div>
    <!-- <div style="width:100%; white-space:nowrap;">
        <span style="display: inline-block; vertical-align: top; padding: 5px; width:10%">
            <div id="palettex" style="background-color: Snow; border: solid 1px gray; height: 800px"></div>
        </span>
        <span style="display: inline-block; vertical-align: top; padding: 5px; width:90%">
            <div id="myDiagramDivx" style="border: solid 1px black; width:100%; height:800px;background-color: #DAE4E4;"></div>
        </span>
        
        <div class="push" style="height:130px;clear: both;"></div>
    </div> -->
    <!-- <div style="min-height:100%;height: auto !important;height: 100%;margin: 0 auto -130px;">
        <div id="myDiagramDiv" style="border: solid 1px black; width:1000px; height:500px;background-color: #DAE4E4;"></div>
        <div class="push" style="height:130px;clear: both;"></div>
    </div> -->
	<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
	<script type="text/javascript">
	$(document).ready(function(){
            editorInit();
			//layout();
			load();
		});
		
		function layout() {
    myDiagram.layoutDiagram(true);
  }
  // Show the diagram's model in JSON format
  function save() {
    document.getElementById("mySavedModel").value = myDiagram.model.toJson();
    myDiagram.isModified = false;
  }
  function load() {
    myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
  }
    function exportToPNG() {
        //document.getElementById('id_image_export').removeChild(imgBlob);
        //myDiagram.zoomToFit();
        var imgBlob = myDiagram.makeImage({
            scale: 0.7,
            background: "AntiqueWhite",
            type: "image/png"
        });
        document.getElementById('id_image_export').innerHTML="";
        document.getElementById('id_image_export').appendChild(imgBlob);
        //alert("ok");
        //$('#id_image_export').empty();
        //$('#id_image_export').append(imgBlob);
    }
    function zoomToFit() {
        myDiagram.zoomToFit();
    }
  function editorInit() {
        var robot;  // this global variable will hold an instance of the Robot class for myDiagram
        var global_conf = {};
        global_conf["description"] = "Input Some Description ...";
        global_conf["global_envs"] = [
            {"Param1":"123456"},
            {"Param2":"654321"},
            {"Param3":"abcd"},
            {"Param4":"dcba"}
        ];
        //var html = '';
        //$("#id_Global_Configurations").html();
        //$("#id_Global_Configurations").append(html);

        var GO = go.GraphObject.make;  // for conciseness in defining templates

    var yellowgrad = GO(go.Brush, "Linear", { 0: "rgb(254, 201, 0)", 1: "rgb(254, 162, 0)" });
    var greengrad = GO(go.Brush, "Linear", { 0: "#98FB98", 1: "#9ACD32" });
    var bluegrad = GO(go.Brush, "Linear", { 0: "#B0E0E6", 1: "#87CEEB" });
    var redgrad = GO(go.Brush, "Linear", { 0: "#C45245", 1: "#7D180C" });
    var whitegrad = GO(go.Brush, "Linear", { 0: "#F0F8FF", 1: "#E6E6FA" });

    var bigfont = "normal 16pt Helvetica, Arial, sans-serif";
    var smallfont = "normal 16pt Helvetica, Arial, sans-serif";

    // Common text styling
    function textStyle() {
      return {
        margin: 6,
        //wrap: go.TextBlock.WrapFit,
        //textAlign: "center",
        editable: true,
        font: smallfont,
        isMultiline: true  // don't allow newlines in text
      }
    }

    myDiagram =
      GO(go.Diagram, "myDiagramDiv",
        {
          // have mouse wheel events zoom in and out instead of scroll up and down
          //"toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
          allowDrop: true,  // support drag-and-drop from the Palette
          //initialAutoScale: go.Diagram.Uniform,
		  scale: 0.7,
          "linkingTool.direction": go.LinkingTool.ForwardsOnly,
          initialContentAlignment: go.Spot.Center,
          layout: GO(go.LayeredDigraphLayout, { isInitial: false, isOngoing: false, layerSpacing: 50 }),
          // allow Ctrl-G to call groupSelection()
          "commandHandler.archetypeGroupData": { text: "Group", isGroup: true, color: "red" },
          "undoManager.isEnabled": true
        });

    // when the document is modified, add a "*" to the title and enable the "Save" button
    myDiagram.addDiagramListener("Modified", function(e) {
      var button = document.getElementById("SaveButton");
      if (button) button.disabled = !myDiagram.isModified;
      var idx = document.title.indexOf("*");
      if (myDiagram.isModified) {
        if (idx < 0) document.title += "*";
      } else {
        if (idx >= 0) document.title = document.title.substr(0, idx);
      }
    });

    var defaultAdornment =
      GO(go.Adornment, "Spot",
        GO(go.Panel, "Auto",
          GO(go.Shape, { fill: null, stroke: "dodgerblue", strokeWidth: 4 }),
          GO(go.Placeholder)),
        // the button to create a "next" node, at the top-right corner
        GO("Button",
          { alignment: go.Spot.TopRight,
            click: addNodeAndLink },  // this function is defined below
          new go.Binding("visible", "", function(a) { return !a.diagram.isReadOnly; }).ofObject(),
          GO(go.Shape, "PlusLine", { desiredSize: new go.Size(6, 6) })
        )
      );

    // define the Node template
    myDiagram.nodeTemplate =
      GO(go.Node, "Auto",
        { selectionAdornmentTemplate: defaultAdornment },
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // define the node's outer shape, which will surround the TextBlock
        GO(go.Shape, "Rectangle",
          { fill: yellowgrad, stroke: "black",
            portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer",
            toEndSegmentLength: 50, fromEndSegmentLength: 40 }),
        GO(go.TextBlock, "Page",
          { margin: 6,
            font: bigfont,
            editable: true },
          new go.Binding("text", "text").makeTwoWay()));

	myDiagram.nodeTemplateMap.add("Default",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // new go.Binding("text", "text"),
        GO(go.Shape, "RoundedRectangle",{ 
          fill: "#FFFFFF",
          portId: "", cursor: "pointer",  // the Shape is the port, not the whole Node
        // allow all kinds of links from and to this port
        fromLinkable: true, fromLinkableSelfNode: false, fromLinkableDuplicates: true,
        toLinkable: true, toLinkableSelfNode: false, toLinkableDuplicates: true
        }),
        GO(go.Panel, "Horizontal",
            GO(go.Picture,
                      // Pictures should normally have an explicit width and height.
                      // This picture has a red background, only visible when there is no source set
                      // or when the image is partially transparent.
                      { source:"/static/images/resources/host.jpg", margin: 2, width: 20, height: 20}
            ),
            GO(go.TextBlock, "HostService", textStyle(), new go.Binding("text", "text").makeTwoWay()
            )
        ), // end Horizontal Panel
        GO(go.TextBlock,
              new go.Binding("text", "instances"),
              { alignment: go.Spot.TopRight, //background: "lightgreen", 
              stroke: "yellowgrad", 
              font: "bold 12pt", editable:false } 
        )
        ));
	
    myDiagram.nodeTemplateMap.add("HostService",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // new go.Binding("text", "text"),
        GO(go.Shape, "RoundedRectangle",{ 
          fill: "#FFFFFF",
          portId: "", cursor: "pointer",  // the Shape is the port, not the whole Node
        // allow all kinds of links from and to this port
        fromLinkable: true, fromLinkableSelfNode: false, fromLinkableDuplicates: true,
        toLinkable: true, toLinkableSelfNode: false, toLinkableDuplicates: true
        }),
        GO(go.Panel, "Horizontal",
            GO(go.Picture,
                      // Pictures should normally have an explicit width and height.
                      // This picture has a red background, only visible when there is no source set
                      // or when the image is partially transparent.
                      { source:"../resources/host.jpg", margin: 2, width: 20, height: 20}
            ),
            GO(go.TextBlock, "HostService", textStyle(), new go.Binding("text", "text").makeTwoWay()
            )
        ), // end Horizontal Panel
        GO(go.TextBlock,
              new go.Binding("text", "instances"),
              { alignment: go.Spot.TopRight, //background: "lightgreen", 
              stroke: "yellowgrad", 
              font: "bold 12pt", editable:false } 
        )
        ));
        
    myDiagram.nodeTemplateMap.add("DockerService",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // new go.Binding("text", "text"),
        GO(go.Shape, "RoundedRectangle",{ 
          fill: "#FFFFFF",
          portId: "", cursor: "pointer",  // the Shape is the port, not the whole Node
        // allow all kinds of links from and to this port
        fromLinkable: true, fromLinkableSelfNode: false, fromLinkableDuplicates: true,
        toLinkable: true, toLinkableSelfNode: false, toLinkableDuplicates: true
        }),
        GO(go.Panel, "Horizontal",
            GO(go.Picture,
                      // Pictures should normally have an explicit width and height.
                      // This picture has a red background, only visible when there is no source set
                      // or when the image is partially transparent.
                      { source:"/static/images/resources/docker.jpg", margin: 2, width: 20, height: 20}),
            GO(go.TextBlock, "DockerService", textStyle(), new go.Binding("text", "text").makeTwoWay()
              )
        ), // end Horizontal Panel
        GO(go.TextBlock,
              new go.Binding("text", "instances"),
              { alignment: go.Spot.TopRight, //background: "lightgreen", 
              stroke: "yellowgrad", 
              font: "bold 12pt", editable:false } 
        )
        ));
    
    myDiagram.nodeTemplateMap.add("APIProxy",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // new go.Binding("text", "text"),
        GO(go.Shape, "RoundedRectangle",{ 
          fill: "#FFFFFF",
          portId: "", cursor: "pointer",  // the Shape is the port, not the whole Node
        // allow all kinds of links from and to this port
        fromLinkable: true, fromLinkableSelfNode: false, fromLinkableDuplicates: true,
        toLinkable: true, toLinkableSelfNode: false, toLinkableDuplicates: true
        }),
        GO(go.Panel, "Horizontal",
            GO(go.Picture,
                      // Pictures should normally have an explicit width and height.
                      // This picture has a red background, only visible when there is no source set
                      // or when the image is partially transparent.
                      { source:"/static/images/resources/proxy.jpg", margin: 2, width: 20, height: 20}),
            GO(go.TextBlock, "APIProxy", textStyle(), new go.Binding("text", "text").makeTwoWay()
              )
        ), // end Horizontal Panel
        GO(go.TextBlock,
              new go.Binding("text", "instances"),
              { alignment: go.Spot.TopRight, //background: "lightgreen", 
              stroke: "yellowgrad", 
              font: "bold 12pt", editable:false } 
        )
        ));
    
    myDiagram.nodeTemplateMap.add("VirtualNode",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // new go.Binding("text", "text"),
        GO(go.Shape, "RoundedRectangle",{ 
          fill: "#FFFFFF",
          portId: "", cursor: "pointer",  // the Shape is the port, not the whole Node
        // allow all kinds of links from and to this port
        fromLinkable: true, fromLinkableSelfNode: false, fromLinkableDuplicates: true,
        toLinkable: true, toLinkableSelfNode: false, toLinkableDuplicates: true
        }),
        GO(go.Panel, "Horizontal",
            GO(go.Picture,
                      // Pictures should normally have an explicit width and height.
                      // This picture has a red background, only visible when there is no source set
                      // or when the image is partially transparent.
                      { source:"/static/images/resources/vnode.jpg", margin: 2, width: 20, height: 20}),
            GO(go.TextBlock, "VirtualNode", textStyle(), new go.Binding("text", "text").makeTwoWay()
              )
        ), // end Horizontal Panel
        GO(go.TextBlock,
              new go.Binding("text", "instances"),
              { alignment: go.Spot.TopRight, //background: "lightgreen", 
              stroke: "yellowgrad", 
              font: "bold 12pt", editable:false } 
        )
        ));
    
    myDiagram.nodeTemplateMap.add("DesiredEvent",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        GO(go.Shape, "RoundedRectangle",
          { fill: greengrad, portId: "", toLinkable: true, toEndSegmentLength: 50 }),
        GO(go.TextBlock, "Success!", textStyle(),
          new go.Binding("text", "text").makeTwoWay())
        ));

    // Undesired events have a special adornment that allows adding additional "reasons"
    var UndesiredEventAdornment =
      GO(go.Adornment, "Spot",
        GO(go.Panel, "Auto",
          GO(go.Shape, { fill: null, stroke: "dodgerblue", strokeWidth: 4 }),
          GO(go.Placeholder)),
        // the button to create a "next" node, at the top-right corner
        GO("Button",
          { alignment: go.Spot.BottomRight,
            click: addReason },  // this function is defined below
          new go.Binding("visible", "", function(a) { return !a.diagram.isReadOnly; }).ofObject(),
          GO(go.Shape, "TriangleDown", { desiredSize: new go.Size(10, 10) })
        )
      );

    var reasonTemplate = GO(go.Panel, "Horizontal",
      GO(go.TextBlock, "Reason",
        {
          margin: new go.Margin(4,0,0,0),
          maxSize: new go.Size(200, NaN),
          wrap: go.TextBlock.WrapFit,
          stroke: "whitesmoke",
          editable: true,
          font: smallfont
        },
        new go.Binding("text", "text").makeTwoWay())
      );


    myDiagram.nodeTemplateMap.add("UndesiredEvent",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        { selectionAdornmentTemplate: UndesiredEventAdornment },
        GO(go.Shape, "RoundedRectangle",
          { fill: redgrad, portId: "", toLinkable: true, toEndSegmentLength: 50 }),
        GO(go.Panel, "Vertical", {defaultAlignment: go.Spot.TopLeft},

          GO(go.TextBlock, "Drop", textStyle(),
            { stroke: "whitesmoke",
              minSize: new go.Size(80, NaN) },
            new go.Binding("text", "text").makeTwoWay()),

          GO(go.Panel, "Vertical",
            { defaultAlignment: go.Spot.TopLeft,
              itemTemplate: reasonTemplate },
            new go.Binding("itemArray", "reasonsList").makeTwoWay()
          )
        )
        ));

    myDiagram.nodeTemplateMap.add("CommentText",
      GO(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        GO(go.Shape, "Rectangle",
          { portId: "", fill: bluegrad, fromLinkable: false }),
        GO(go.TextBlock, "CommentText",
          { margin: 9,
            maxSize: new go.Size(1000, NaN),
            wrap: go.TextBlock.WrapFit,
            editable: true,
            font: bigfont },
          new go.Binding("text", "text").makeTwoWay())
        // no ports, because no links are allowed to connect with a comment
        ));

    // clicking the button on an UndesiredEvent node inserts a new text object into the panel
    function addReason(e, obj) {
      var adorn = obj.part;
      if (adorn === null) return;
      e.handled = true;
      var arr = adorn.adornedPart.data.reasonsList;
      myDiagram.startTransaction("add reason");
      myDiagram.model.addArrayItem(arr, {});
      myDiagram.commitTransaction("add reason");
    }

    // clicking the button of a default node inserts a new node to the right of the selected node,
    // and adds a link to that new node
    function addNodeAndLink(e, obj) {
      var adorn = obj.part;
      if (adorn === null) return;
      e.handled = true;
      var diagram = adorn.diagram;
      diagram.startTransaction("Add State");
      // get the node data for which the user clicked the button
      var fromNode = adorn.adornedPart;
      var fromData = fromNode.data;
      // create a new "State" data object, positioned off to the right of the adorned Node
      var toData = { text: "new" };
      var p = fromNode.location;
      toData.loc = p.x + 200 + " " + p.y;  // the "loc" property is a string, not a Point object
      // add the new node data to the model
      var model = diagram.model;
      model.addNodeData(toData);
      // create a link data from the old node data to the new node data
      var linkdata = {};
      linkdata[model.linkFromKeyProperty] = model.getKeyForNodeData(fromData);
      linkdata[model.linkToKeyProperty] = model.getKeyForNodeData(toData);
      // and add the link data to the model
      model.addLinkData(linkdata);
      // select the new Node
      var newnode = diagram.findNodeForData(toData);
      diagram.select(newnode);
      diagram.commitTransaction("Add State");
    }

    // replace the default Link template in the linkTemplateMap
    myDiagram.linkTemplate =
      GO(go.Link,  // the whole link panel
        new go.Binding("points").makeTwoWay(),
        { //routing: go.Link.AvoidsNodes,  // may be either Orthogonal or AvoidsNodes
        //curve: go.Link.JumpOver //},
		
        //routing: go.Link.Normal//,
        //curve: go.Link.Bezier//,
        //toShortLength: 8
        },
        //new go.Binding("curviness", "curviness"),
        /*GO(go.Shape,  // the link shape
          { stroke: "black", strokeWidth: 1.0 }),*/
        GO(go.Shape),
		GO(go.Shape, { toArrow: "OpenTriangle", fill: null })
    );
    
    /*myDiagram.linkTemplate =
    GO(go.Link,
      //{ curve: go.Link.Bezier },  // Bezier curve
      GO(go.Shape),
      GO(go.Shape, { toArrow: "Standard" })
    );*/
    
    myDiagram.linkTemplateMap.add("Comment",
      GO(go.Link, { selectable: false },
        GO(go.Shape, { strokeWidth: 2, stroke: "darkgreen" })));
        
    // Groups consist of a title in the color given by the group node data
    // above a translucent gray rectangle surrounding the member parts
    myDiagram.groupTemplate =
      GO(go.Group, "Vertical",
        { selectionObjectName: "PANEL",  // selection handle goes around shape, not label
          ungroupable: true },  // enable Ctrl-Shift-G to ungroup a selected Group
        GO(go.TextBlock,
          {
            font: "bold 16px sans-serif",
            isMultiline: false,  // don't allow newlines in text
            editable: true,  // allow in-place editing by user,
			fromLinkable: true, 
			toLinkable: true
          },
          new go.Binding("text", "text").makeTwoWay(),
          new go.Binding("stroke", "color")),
        GO(go.Panel, "Auto",
          { name: "PANEL" },
          GO(go.Shape, "Rectangle",  // the rectangular shape around the members
            { fill: "rgba(128,128,128,0.2)", stroke: "gray", strokeWidth: 1 , fromLinkable: true, toLinkable: true}),
          GO(go.Placeholder, { padding: 10 })  // represents where the members are
        )
      );


    // a shared Robot that can be used by all commands for this one Diagram
    robot = new Robot(myDiagram);  // defined in Robot.js

    /*var palette =
      GO(go.Palette, "palette",  // create a new Palette in the HTML DIV element "palette"
        {
          // share the template map with the Palette
          nodeTemplateMap: myDiagram.nodeTemplateMap,
          autoScale: go.Diagram.Uniform  // everything always fits in viewport
        });

    palette.model.nodeDataArray = [
      { category: "HostService",text:"HostService", instances:"" },
      { category: "DockerService",text:"DockerService", instances:"" },
      { category: "APIProxy",text:"APIProxy", instances:"" },
      //{ }, // default node
      //{ category: "DesiredEvent" },
      { category: "VirtualNode",text:"VirtualNode", instances:"" },
      //{ category: "UndesiredEvent", reasonsList: [{}] },
      { category: "CommentText"}
    ];*/

    // read in the JSON-format data from the "mySavedModel" element
    
    load();
    //layout();
    
    function showMessage(s) {
    document.getElementById("diagramEventsMsg").textContent = s;
  }
    myDiagram.addDiagramListener("ObjectSingleClicked",
      function(e) {
        var part = e.subject.part;
        //if (!(part instanceof go.Link)) showMessage("Clicked on " + part.data.key);
        showMessage("Clicked on " + part.data.key + " : " + part.data.text);
        $("#pageTab > .active").removeClass('active');
        $("#pageTabContent > .active").removeClass('active');
        $("#id_Node_Configurations_li").addClass("active");
        $("#id_Node_Configurations").addClass("active");
      });
    myDiagram.addDiagramListener("BackgroundSingleClicked",
      function() {
        //var part = e.subject.part;
        //if (!(part instanceof go.Link)) showMessage("Clicked on " + part.data.key);
        showMessage("Clicked on bk");
        $("#pageTab > .active").removeClass('active');
        $("#pageTabContent > .active").removeClass('active');
        $("#id_Global_Configurations_li").addClass("active");
        $("#id_Global_Configurations").addClass("active");
      });
}

	</script>
</body>
</html>
